package org.dolphin.generator;

import java.util.Random;

public final class SecurePasswordGenerator {
  public static final String ALPHA_CAPS_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  public static final String ALPHA_CHARS = "abcdefghijklmnopqrstuvwxyz";
  public static final String NUMERIC = "0123456789";
  public static final String SPECIAL_CHARS = "!@#$%&{}_+-/";

  public static String generatePassword(int minimumLength, int maximumLength, int noOfCapsChars,
      int noOfDigits, int noOfSpecialChars) {
    if (minimumLength <= 0) {
      throw new IllegalArgumentException("Invalid minimum length");
    }
    if (minimumLength > maximumLength) {
      throw new IllegalArgumentException("Minimum length should be less or equal to maximum length");
    }
    if (noOfCapsChars + noOfDigits + noOfSpecialChars > minimumLength) {
      throw new IllegalArgumentException("Invalid minimum length (wrong total of combination)");
    }
    Random random = new Random();
    int len = maximumLength == minimumLength ? maximumLength : random.nextInt(maximumLength
        - minimumLength + 1)
        + minimumLength;
    char[] password = new char[len];
    for (int i = 0; i < noOfCapsChars; i++) {
      int index = getNextIndex(random, len, password);
      password[index] = ALPHA_CAPS_CHARS.charAt(random.nextInt(ALPHA_CAPS_CHARS.length()));
    }
    for (int i = 0; i < noOfDigits; i++) {
      int index = getNextIndex(random, len, password);
      password[index] = NUMERIC.charAt(random.nextInt(NUMERIC.length()));
    }
    for (int i = 0; i < noOfSpecialChars; i++) {
      int index = getNextIndex(random, len, password);
      password[index] = SPECIAL_CHARS.charAt(random.nextInt(SPECIAL_CHARS.length()));
    }
    for (int i = 0; i < len; i++) {
      if (password[i] == 0) {
        password[i] = ALPHA_CHARS.charAt(random.nextInt(ALPHA_CHARS.length()));
      }
    }
    return new String(password).intern();
  }

  private static int getNextIndex(Random random, int len, char[] password) {
    int index = random.nextInt(len);
    while (password[index = random.nextInt(len)] != 0) {
    }
    return index;
  }
}
